﻿/*
 * BNumber
 * 
 * Author: snowdreamist
 * Date: 2011/11/19
 * 
 */

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BitTorrentSharp.Helpers;

namespace BitTorrentSharp.BEncoding
{
    public class BNumber : BValue
    {
        public BNumber() { }

        public BNumber(long value)
        {
            this.Value = value;
        }

        public static implicit operator BNumber(int value)
        {
            return new BNumber((long)value);
        }

        public static implicit operator BNumber(long value)
        {
            return new BNumber(value);
        }

        public static implicit operator long(BNumber source)
        {
            if (source == null)
                return default(long);
            else
                return source.Value;
        }

        /// <summary>
        /// the value
        /// </summary>
        public long Value { get; set; }

        #region overriders

        internal protected override void InternalDeserialize(BinaryReader reader)
        {
            char topChar = (char)reader.PeekChar();
            if (topChar != 'i')
                throw new BEncodingException(string.Format("Not a number, input {0}", topChar));
            
            reader.ReadChar();
            string numberStr = reader.ReadStringUntil((byte)'e');
            long value;
            if (!long.TryParse(numberStr, out value))
                throw new BEncodingException(string.Format("Cannot convert {0} to number", numberStr));
            this.Value = value;
        }

        internal protected override void InternalSerialize(BinaryWriter writer)
        {
            writer.Write((byte)'i');
            writer.Write(Encoding.Default.GetBytes(this.Value.ToString()));
            writer.Write((byte)'e');
        }
        /// <summary>
        /// Serialize content equals to serialize
        /// </summary>
        /// <param name="writer"></param>
        protected internal override void InternalSerializeContent(BinaryWriter writer)
        {
            this.InternalSerialize(writer);
        }

        public override string ToString()
        {
            return this.Value.ToString();
        }

        #endregion
    }
}
